﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using GraphSharp.Helpers;
using XmlStudio.Controls.Interfaces;
using XmlStudio.Helper;
using XmlStudio.Settings;

namespace GraphSharp.Controls {
    /// <summary>
    /// Logical representation of a param.
    /// </summary>
    [TemplatePart(Name = "PART_Appearance", Type = typeof(Control))]
    [TemplatePart(Name = "PART_ResizeDecorator", Type = typeof(Control))]
    public class VertexControl : Control, IPoolObject, IDisposable, ISelectable {
        private ControlTemplate DefaultAppearance {
            get {
                return Application.Current.TryFindResource(DefaultAppearanceName) as ControlTemplate;
            }
        }

        private string DefaultAppearanceName {
            get { return "AppearanceProcess"; }
        }

        #region VertexProperty
        public object Vertex {
            get { return GetValue(VertexProperty); }
            set { SetValue(VertexProperty, value); }
        }

        public static readonly DependencyProperty VertexProperty =
            DependencyProperty.Register("Vertex", typeof(object), typeof(VertexControl), new UIPropertyMetadata(null));
        #endregion

        #region RootCanvasProperty
        public GraphCanvas RootCanvas {
            get { return (GraphCanvas)GetValue(RootCanvasProperty); }
            set { SetValue(RootCanvasProperty, value); }
        }

        public static readonly DependencyProperty RootCanvasProperty =
            DependencyProperty.Register("RootCanvas", typeof(GraphCanvas), typeof(VertexControl), new UIPropertyMetadata(null));
        #endregion

        #region AppearanceTemplateProperty
        /// <summary>
        /// Gets or sets the AppearancaTemplateProperty.
        /// </summary>
        public ControlTemplate AppearanceTemplate {
            get { return (ControlTemplate)GetValue(AppearanceTemplateProperty); }
            set { SetValue(AppearanceTemplateProperty, value); }
        }
        /// <summary>
        /// Identifies the XmlVisualizer.DiagramDesigner.DesignerItem.AppearanceTemplateProperty.
        /// </summary>
        public static readonly DependencyProperty AppearanceTemplateProperty =
            DependencyProperty.RegisterAttached("AppearanceTemplate", typeof(ControlTemplate), typeof(VertexControl));

        /// <summary>
        /// Gets or sets the name of the appearance template.
        /// </summary>
        public string AppearanceTemplateName { get; set; }
        #endregion

        #region FillBrushProperty
        public Brush FillBrush {
            get { return (Brush)GetValue(FillBrushProperty); }
            set { SetValue(FillBrushProperty, value); }
        }

        public static readonly DependencyProperty FillBrushProperty =
            DependencyProperty.Register("FillBrush", typeof(Brush), typeof(VertexControl), new FrameworkPropertyMetadata(XmlStudioSettings.Instance.VertexDefaultFillBrush));
        #endregion

        #region StrokeBrushProperty
        public Brush StrokeBrush {
            get { return (Brush)GetValue(StrokeBrushProperty); }
            set { SetValue(StrokeBrushProperty, value); }
        }

        public static readonly DependencyProperty StrokeBrushProperty =
            DependencyProperty.Register("StrokeBrush", typeof(Brush), typeof(VertexControl),
                new FrameworkPropertyMetadata(new SolidColorBrush(Colors.Black)));
        #endregion

        //#region HighlightedVertexBackgroundBrush
        //public Brush HighlightedVertexBackgroundBrush {
        //    get { return (Brush)GetValue(HighlightedVertexBackgroundBrushProperty); }
        //    set { SetValue(HighlightedVertexBackgroundBrushProperty, value); }
        //}

        //public static readonly DependencyProperty HighlightedVertexBackgroundBrushProperty =
        //    DependencyProperty.Register("HighlightedVertexBackgroundBrush", typeof(Brush), typeof(VertexControl),
        //    new PropertyMetadata(XmlStudioSettings.Instance.HighlightedVertexBackgroundBrush));
        //#endregion

        // HighlightedVertexBackgroundBrush, HighlightedVertexBorderBrush, HighlightedVertexForegroundBrush, SelectedVertexBackgroundBrush,
        // SemiHighlightedSourceVertexBorderBrush, SemiHighlightedSourceVertexBackgroundBrush, SemiHighlightedTargetVertexBorderBrush, SemiHighlightedTargetVertexBackgroundBrush
        // HighlightedEdgeBrush, SemiHighlightedInEdgeBrush, SemiHighlightedOutEdgeBrush

        static VertexControl() {
            //override the StyleKey Property
            DefaultStyleKeyProperty.OverrideMetadata(typeof(VertexControl), new FrameworkPropertyMetadata(typeof(VertexControl)));
        }

        public VertexControl() {
            if(DefaultAppearance != null) {
                this.AppearanceTemplate = DefaultAppearance;
                this.AppearanceTemplateName = DefaultAppearanceName;
                this.ApplyTemplate();
            }
        }

        #region IPoolObject Members

        public void Reset() {
            Vertex = null;
        }

        public void Terminate() {
            //nothing to do, there are no unmanaged resources
        }

        public event DisposingHandler Disposing;

        public void Dispose() {
            if(Disposing != null)
                Disposing(this);
        }

        #endregion

        #region ISelectable Members
        /// <summary>
        /// Gets or sets the IsSelectedProperty.
        /// </summary>
        public bool IsSelected {
            get { return (bool)GetValue(IsSelectedProperty); }
            set { SetValue(IsSelectedProperty, value); }
        }
        /// <summary>
        /// Identifies the XmlVisualizer.DiagramDesigner.DesignerItem.IsSelectedProperty.
        /// </summary>
        public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(VertexControl),
            new FrameworkPropertyMetadata(false, IsSelectedProperty_PropertyChanged));

        private static void IsSelectedProperty_PropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e) {
            //if (o is DesignerItem)
            //{
            //    DesignerItem item = o as DesignerItem;

            //    if ((bool)e.NewValue == true)
            //    {
            //        item.OldFillBrush = item.FillBrush;
            //        if (item.FillBrush is SolidColorBrush)
            //        {
            //            SolidColorBrush brush = item.FillBrush as SolidColorBrush;
            //            Color color = Color.Multiply(brush.Color, 1.8f);
            //            SetFillBrushProperty((UIElement)o, new SolidColorBrush(color));
            //        }
            //    }
            //    else
            //    {
            //        if (item.OldFillBrush != null)
            //            SetFillBrushProperty((UIElement)o, item.OldFillBrush);
            //    }
            //}
        }
        #endregion

        protected override void OnPreviewMouseDown(MouseButtonEventArgs e) {
            base.OnPreviewMouseDown(e);

            SelectionService selectionService = SelectionService.GetCurrentInstance(this as DependencyObject);

            if(selectionService != null) {
                if((Keyboard.Modifiers & (ModifierKeys.Shift | ModifierKeys.Control)) != ModifierKeys.None)
                    if(this.IsSelected) {
                        selectionService.RemoveFromSelection(this);
                    } else {
                        selectionService.AddToSelection(this);
                    } else if(!this.IsSelected) {
                    selectionService.SelectItem(this);
                }

                //Focus();
                e.Handled = false;
            }
        }
    }
}